#!/usr/bin/python

import os
import sys
import tempfile
import optparse
import subprocess

def get_ranges(fname, field_num):
    max_range = float('-inf')
    min_range = float('inf')
    fobj = open(fname)
    for line in fobj:
        range = float(line.split()[field_num])
        if max_range < range:
            max_range = range
        if min_range > range:
            min_range = range
    return min_range, max_range

def main(opts):
    if opts.input_file:
        input_file = opts.input_file
    else:
        temp_input_file = tempfile.NamedTemporaryFile(delete=False)
        temp_input_file.writelines(sys.stdin)
        temp_input_file.close()
        input_file = temp_input_file.name
    if opts.output_file:
        output_file = opts.output_file
    else:
        temp_output_file = tempfile.NamedTemporaryFile(delete=False)
        temp_output_file.close()
        output_file = temp_output_file.name

    min_yrange, max_yrange = get_ranges(input_file, 1)
    min_yrange = (min_yrange > max_yrange * 0.05 or min_yrange < 0) and min_yrange - max_yrange * 0.05 or 0.0
    max_yrange = max_yrange * 1.05 - min_yrange * 0.05
    
    min_xrange, max_xrange = get_ranges(input_file, 0)
    min_xrange = (min_xrange > max_xrange * 0.05 or min_xrange < 0) and min_xrange - max_xrange * 0.05 or 0.0
    max_xrange = max_xrange * 1.05 - min_xrange * 0.05
        
    if opts.xmin != None:
        min_xrange = opts.xmin
    if opts.xmax != None:
        max_xrange = opts.xmax
    if opts.ymin != None:
        min_yrange = opts.ymin
    if opts.ymax != None:
        max_yrange = opts.ymax

    gnuplot_cmd = ""
    if opts.title:
        gnuplot_cmd += """\n set title "%s"\n""" % opts.title
    if opts.hist:
        gnuplot_cmd += """
        set style histogram rowstacked
        set style data histograms
        """

    gnuplot_cmd += """
        set terminal png size 1000
        set output "%s"
        set boxwidth 0.75 absolute
        set style fill solid 1.00 border -1
        set xtics 1000 nomirror
        set xtic rotate by -45 scale 0
        set ytics 100 nomirror
        set mxtics 2
        set mytics 2
        set ytics %s
        set xtics %s        
        set yrange [%s:%s]
        set xrange [%s:%s]
        set ylabel "%s"
        set xlabel "%s"
        
        plot '%s' using 2 lt 1 t "Data"
    """
    gnuplot_cmd = gnuplot_cmd % (
        output_file,
        max(1, int(max_yrange / 10)),
        max(1, int(max_xrange / 10)),
        (min_yrange > max_yrange * 0.05 or min_yrange < 0) and min_yrange - max_yrange * 0.05 or 0.0,
        max_yrange * 1.05 - min_yrange * 0.05,
        (min_xrange > max_xrange * 0.05 or min_xrange < 0) and min_xrange - max_xrange * 0.05 or 0.0,
        max_xrange * 1.05 - min_xrange * 0.05,
        opts.ylabel,
        opts.xlabel,
        input_file,
    )
    #print gnuplot_cmd
    p = subprocess.Popen("/usr/bin/gnuplot  <<EOF %s \nEOF" % gnuplot_cmd, shell=True)
    p.wait()
    if not opts.output_file:
        sys.stdout.write(open(output_file).read())
        os.unlink(output_file)
    if not opts.input_file:
        os.unlink(input_file)


if __name__ == "__main__":
    parser = optparse.OptionParser(
        usage = '%prog -i INPUT_FILE ',
    )
    parser.add_option(
        '-i', '--input-file',
        dest    = 'input_file',
        metavar = 'INPUT_FILE',
    )
    parser.add_option(
        '-o', '--output-file',
        dest    = 'output_file',
        metavar = 'OUTPUT_FILE',
    )
    parser.add_option(
        '--hist',
        dest    = 'hist',
        action  = 'store_true',
        default = False,
    )
    parser.add_option(
        '-x', '--xlabel',
        dest    = 'xlabel',
        default = 'X',
    )
    parser.add_option(
        '-y', '--ylabel',
        dest    = 'ylabel',
        default = 'Y',
    )
    parser.add_option(
        '-t', '--title',
        dest    = 'title',
        default = 'title',
    )
    parser.add_option(
        '--xmin',
        dest    = 'xmin',
        type    = 'float',
    )
    parser.add_option(
        '--xmax',
        dest    = 'xmax',
        type    = 'float',
    )
    parser.add_option(
        '--ymin',
        dest    = 'ymin',
        type    = 'float',
    )
    parser.add_option(
        '--ymax',
        dest    = 'ymax',
        type    = 'float',
    )
        
        
    options, args = parser.parse_args()

    main(options)
